#include <iostream>
using std::cout;
using std::endl;

template <class T> //模板一
T add(T t1,T t2)
{
    cout << "T class" << endl;
    return t1 + t2; 
}


template <class T1, class T2>  //模板二
T1 add(T1 t1, T2 t2)
{
    cout << "T1 T2" << endl;
    /* cout << t1 + t2 << endl; */
    return t1 + t2;
}


void test0(){
    short s1 = 1, s2 = 2;
    int i1 = 3, i2 = 4;
    long l1 = 5, l2 = 6;
    double d1 = 1.4, d2 = 2.8;
    cout << add(d1,i2) << endl; 
    cout << add(i1,d2) << endl;
}

void test1(){
    int x = 10;
    double y = 9.2;
    double z = 9.9;
    //有了模板二之后，显式实例化时可以指定两个类型参数
    cout << add<int,int>(x,y) << endl; //模板二
    cout << add<int,double>(x,y) << endl; //模板二

    //指定了T1类型为int，没有指定T2类型
    cout << add<int>(x,y) << endl;
    //能够隐式实例化尽量使用隐式实例化
    cout << add(x,y) << endl;
    cout << add(y,x) << endl;

    cout << add(y,z) << endl;

    cout << endl;
    //注意：不推荐如下写法
    //指定了返回类型是int
    //对照模板二，发现第一个参数也得是int
    //实际传入的y是double
    //再对照模板一，模板一只有一个类型参数
    //就直接使用了（对y进行类型转换）
    cout << add<int>(y,x) << endl; 
}

int main(void){
    test1();
    return 0;
}
